package com.ceshiren.chnjx.wework.page;

import com.ceshiren.chnjx.wework.common.Constant;
import com.ceshiren.chnjx.wework.exception_handle.ExceptionHandler;
import com.ceshiren.chnjx.wework.utils.FileUtils;
import io.appium.java_client.AppiumDriver;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.File;
import java.time.Duration;
import java.util.List;

/**
 * @author JJJJ
 * @Title: basePage
 * @date 2021/11/6下午4:18
 * @Description: page的父类
 */
public class BasePage {

    public AppiumDriver driver;
    private WebElement currentElement;

    public BasePage(AppiumDriver driver){
        this.driver = driver;
    }
    public BasePage(){}

    public void screenshot(){
        long now = System.currentTimeMillis();
        File screenshot = driver.getScreenshotAs(OutputType.FILE);
        String pwd = "/Users/chnjx/IdeaProjects/appium_test/src/test/test_result/image/";
        try {
            FileUtils.copyFile(driver.getScreenshotAs(OutputType.FILE),new File(pwd + now));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 获取元素
     * @param locator 定位符
     * @return self
     */
    public BasePage findEle(By locator){
        try {
            currentElement = driver.findElement(locator);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return this;
    }

    /**
     * 等待元素可见 并获取元素
     * @param locator 定位符
     *
     */
    public BasePage waiteElementVisibility(By locator){
        try {
            WebDriverWait webDriverWait = new WebDriverWait(driver,Duration.ofSeconds(Constant.WAIT_TIME));
            currentElement = webDriverWait.until(ExpectedConditions.visibilityOfElementLocated(locator));
        }catch (Exception e){
            String pageSource = driver.getPageSource();
            if (ExceptionHandler.currentRetryTime++ < ExceptionHandler.MAX_RETRY_TIME){
                ExceptionHandler.getAllException().forEach(exceptionHandler -> {
                    if (exceptionHandler.isHit(pageSource)){
                        exceptionHandler.handle(driver);
                        waiteElementVisibility(locator);
                    }
                });
            }
            screenshot();
            throw e;
        }
        return this;
    }

    /**
     * 等待元素可被点击 并获取元素
     * @param locator 定位符
     */
    public BasePage waiteElementClickable(By locator){
        try {
            WebDriverWait webDriverWait = new WebDriverWait(driver,Duration.ofSeconds(Constant.WAIT_TIME));
            currentElement = webDriverWait.until(ExpectedConditions.elementToBeClickable(locator));
        }catch (Exception e){
            String pageSource = driver.getPageSource();
            if (ExceptionHandler.currentRetryTime++ < ExceptionHandler.MAX_RETRY_TIME){
                ExceptionHandler.getAllException().forEach(exceptionHandler -> {
                    if (exceptionHandler.isHit(pageSource)){
                        exceptionHandler.handle(driver);
                        waiteElementClickable(locator);
                    }
                });
            }
            screenshot();
            throw e;
        }
        return this;
    }

    public List<WebElement> findElements(By by){
        return driver.findElements(by);
    }

    /**
     * 点击元素  需要先获取元素
     */
    public BasePage click(){
        currentElement.click();
        return this;
    }

    /**
     * 点击元素
     * @param locator 元素定位符
     */
    public BasePage click(By locator){
        findEle(locator).click();
        return this;
    }

    /**
     * 输入数据
     * @param date 要输入的数据
     */
    public BasePage sendDate(String date){
        currentElement.sendKeys(date);
        return this;
    }

    /**
     * 输入数据
     * @param locator 元素定位符
     * @param date 数据
     */
    public BasePage sendDate(By locator,String date){
        findEle(locator).sendDate(date);
        return this;
    }

    /**
     * 获取元素文本 需要先获取元素
     */
    public String getElementText(){
        return currentElement.getAttribute("text");
    }

    /**
     * 获取元素文本
     * @param locator 元素定位符
     */
    public String getElementText(By locator){
        findElements(locator);
        return currentElement.getAttribute("text");
    }

    /**
     * 获取元素属性 需要先获取元素
     * @param attribute 元素名称
     */
    public String getElementAttribute(String attribute){
        return currentElement.getAttribute(attribute);
    }

    /**
     * 获取元素属性
     * @param locator 元素定位符
     * @param attribute 元素名称
     */
    public String getElementAttribute(By locator,String attribute){
        findEle(locator);
        return currentElement.getAttribute(attribute);
    }

    /**
     * 向下滑动
     */
    public BasePage swipeDown(){
        int height = driver.manage().window().getSize().height;
        int wight  = driver.manage().window().getSize().width;
        TouchAction touchAction = new TouchAction((AndroidDriver)driver);

        Duration duration = Duration.ofMillis(600);
        touchAction
                .press(PointOption.point(wight/2,height*2/3))
                .waitAction(WaitOptions.waitOptions(duration))
                .moveTo(PointOption.point(wight/2,height/4))
                .release()
                .perform();
        return this;
    }

    /**
     * 滑动到元素所在位置并获取元素
     * @param locator 元素定位符
     * @return
     */
    public BasePage swipeDownUntilEleVisible(By locator){
        String oldPage = driver.getPageSource();
        while (true){
            try {
                currentElement = driver.findElement(locator);
                break;
            }catch (Exception e){
                swipeDown();
                String newPage = driver.getPageSource();
                if (newPage.equals(oldPage)){
                    System.out.println("没有找到元素");
                    throw e;
                }else {
                    oldPage = newPage;
                }
            }
        }
        return this;

    }
}
